package org.beetl.sql.ext.jpa.mapper.ready;

import java.lang.reflect.Method;
import java.util.ArrayList;

import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.SQLReady;
import org.beetl.sql.core.page.DefaultPageRequest;
import org.beetl.sql.core.page.DefaultPageResult;
import org.beetl.sql.core.page.PageRequest;
import org.beetl.sql.core.page.PageResult;
import org.beetl.sql.mapper.builder.MethodParamsHolder;
import org.beetl.sql.mapper.builder.ReturnTypeParser;
import org.beetl.sql.mapper.ready.PageSqlReadyMI;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

public class JpaDataPageSqlReadyMI extends PageSqlReadyMI {

	private final String countSql;
	private final MethodParamsHolder holder;
	private final boolean pageResultRequired;
//	private Class targetType;
	private ReturnTypeParser returnTypeParser;
	private String sql;

	public JpaDataPageSqlReadyMI(String sql, ReturnTypeParser returnTypeParser, boolean pageResultRequired,
			MethodParamsHolder paramsHolder) {
		super(sql, returnTypeParser.getPageResultType(), pageResultRequired, paramsHolder);
		this.countSql = null;
		this.holder = paramsHolder;
		this.pageResultRequired = pageResultRequired;
		this.returnTypeParser = returnTypeParser;
		this.sql = sql;
	}

	public JpaDataPageSqlReadyMI(String sql, ReturnTypeParser returnTypeParser, boolean pageResultRequired, MethodParamsHolder paramsHolder,
			String countSql) {
		super(sql, returnTypeParser.getPageResultType(), pageResultRequired, paramsHolder);
		this.countSql = countSql;
		this.holder = paramsHolder;
		this.pageResultRequired = pageResultRequired;
		this.returnTypeParser = returnTypeParser;
		this.sql = sql;
	}


	
	@Override
	public Object call(SQLManager sm, Class entityClass, Method m, Object[] args) {
//		return super.call(sm, entityClass, m, args);
		Object[] newArgs = holder.getArgsExcludePageRequest(args);
		SQLReady sqlReady = new SQLReady(getSqId(sm, entityClass, m), sql, newArgs);
		Object pageArg = args[holder.getPageRequestIndex()];
		PageRequest pageRequest = null;
		Long count = null;
		boolean isEmpty = true;
		long totalPage = 0;
		Pageable p = null;
		boolean isJpaResult = this.returnTypeParser.getType().isAssignableFrom(org.springframework.data.domain.Page.class);
		if (pageArg instanceof org.springframework.data.domain.PageRequest) {
			count = sm.execute(new SQLReady(countSql, newArgs), Long.class).get(0);//计算出总数
			org.springframework.data.domain.PageRequest opageArg = (org.springframework.data.domain.PageRequest) pageArg;
			isEmpty = count == null || count < 1;
			if (isEmpty) {
				if(isJpaResult) {
					return new PageImpl(new ArrayList(),p,0);
				}
				return DefaultPageRequest.of(opageArg.getPageNumber(), opageArg.getPageSize()).of(new ArrayList(), 0L);
			}
			totalPage = Math.toIntExact(count % opageArg.getPageSize() == 0 ? (count / opageArg.getPageSize()) : (count / opageArg.getPageSize() + 1));
			pageRequest = DefaultPageRequest.of(opageArg.getPageNumber(), opageArg.getPageSize(),false);
		} else {
			pageRequest = (PageRequest) pageArg;
		}
		PageResult pageResult = sm.execute(sqlReady, this.returnTypeParser.getPageResultType(), pageRequest);
		if(pageResult instanceof DefaultPageResult && !isEmpty && isJpaResult) {
//			DefaultPageResult dpr = (DefaultPageResult)pageResult;
//			dpr.setTotalRow(count);
//			dpr.setTotalPage(totalPage);
//			pageResult= dpr;
			
			return new PageImpl(pageResult.getList(),p,count);
		}
		
//TODO 暂时不知道怎么搞这个分页
//      if(StringKit.isNotBlank(countSql) && pageRequest instanceof Page) {
//    	long total = sm.execute(new SQLReady(countSql), Long.class).get(0);
//    }
		if (pageResultRequired) {
			return pageResult;
		} else {
			return pageResult.getList();
		}
	}

}
